home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / GDIDIB.PAK / FILENEW.C < prev    next >
C/C++ Source or Header  |  1997-05-06  |  19KB  |  577 lines

  1. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  2. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  3. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  4. // PARTICULAR PURPOSE.
  5. //
  6. // Copyright (C) 1993 - 1995  Microsoft Corporation.  All Rights Reserved.
  7. //
  8. //  MODULE:   filenew.c
  9. //
  10. //  PURPOSE:   Displays the "File New" dialog box
  11. //
  12. //  FUNCTIONS:
  13. //    CmdNew               - Displays the "File New" dialog box
  14. //    FileNew              - Processes messages for "File New" dialog box.
  15. //    MsgFileNewInit       - To initialize the File New dialog box
  16. //    MsgFileNewCommand    - Process WM_COMMAND message sent to the FileNew box. 
  17. //    CmdFileNewEditNotify - Validate bitmap size entered in File New dialog box.
  18. //    CmdFileNewDone       - Free the File New dialog box.
  19. //                      
  20. //  COMMENTS:
  21. //
  22. //
  23.  
  24. #include <windows.h>            // required for all Windows applications
  25. #include <windowsx.h>   
  26. #include <commctrl.h>           // prototypes and structure for the common controls.
  27.  
  28. #include "globals.h"            // prototypes specific to this application  
  29. #include "resource.h"
  30. #include "toolbar.h"
  31. #include "statbar.h"  
  32. #include "palette.h"
  33. #include "dibutil.h"
  34.  
  35. LRESULT CALLBACK FileNew(HWND, UINT, WPARAM, LPARAM);
  36. LRESULT MsgFileNewInit(HWND, UINT, WPARAM, LPARAM);
  37. LRESULT MsgFileNewCommand(HWND, UINT, WPARAM, LPARAM);
  38. LRESULT CmdFileNewEditNotify(HWND, WORD, WORD, HWND);
  39. LRESULT CmdFileNewDone(HWND, WORD, WORD, HWND);
  40.  
  41. // FileNew dialog message table definition.
  42. MSD rgmsdFileNew[] =
  43. {
  44.     {WM_COMMAND,    MsgFileNewCommand},
  45.     {WM_INITDIALOG, MsgFileNewInit}
  46. };
  47.  
  48. MSDI msdiFileNew =
  49. {
  50.     sizeof(rgmsdFileNew) / sizeof(MSD),
  51.     rgmsdFileNew,
  52.     edwpNone
  53. };
  54.  
  55. // FileNew dialog command table definition.
  56. CMD rgcmdFileNew[] =
  57. {
  58.     {IDD_WIDTH,  CmdFileNewEditNotify},
  59.     {IDD_HEIGHT, CmdFileNewEditNotify},
  60.     {IDOK,       CmdFileNewDone},
  61.     {IDCANCEL,   CmdFileNewDone}
  62. };
  63.  
  64. CMDI cmdiFileNew =
  65. {
  66.     sizeof(rgcmdFileNew) / sizeof(CMD),
  67.     rgcmdFileNew,
  68.     edwpNone
  69. };
  70.  
  71. // Module specific "globals"  Used when a variable needs to be
  72. // accessed in more than on handler function.
  73.          
  74. // some arbitrary bitmap sizes                           
  75. #define DEFBITMAPSIZE 256                 // default bitmap width or height
  76. #define MAXBITMAPSIZE 2048                // maximum allowable width or height
  77. #define NOBITMAPSIZE  (MAXBITMAPSIZE + 1) // width or height edit control empty
  78.          
  79. // specification for new bitmap
  80. UINT cxNewWidth;
  81. UINT cyNewHeight;
  82. UINT uNewBitsPerPixel;
  83.  
  84. // flag to prevent recursion in FileNewEditNotify
  85. BOOL fInEditNotify = FALSE;
  86.  
  87. //
  88. //  FUNCTION: CmdNew(HWND, WORD, WORD, HWND)
  89. //
  90. //  PURPOSE: Call the open common dialog and show its results.
  91. //
  92. //  PARAMETERS:
  93. //    hwnd     - The window handle.
  94. //    wCommand - IDM_FILENEW
  95. //    wNotify  - Notification number (unused)
  96. //    hwndCtrl - NULL (Unused)
  97. //
  98. //  RETURN VALUE:
  99. //    Always returns 0 - command handled.
  100. //
  101. //  COMMENTS:
  102. //    To process the IDM_FILENEW message, call DialogBox() to display the
  103. //    FileNew dialog box.
  104. //
  105.  
  106. #pragma argsused
  107. LRESULT CmdNew(HWND hwnd, WORD wCommand, WORD wNotify, HWND hwndCtrl)
  108. {   
  109.     HDC hdc;    
  110.     LPBITMAPINFOHEADER lpbih;    
  111.     char szBuffer[50];   
  112.      int  cbWritten;
  113.      int nResult;
  114.      int nNumColors;         // number of colors supposed to be in color table
  115.      int nColorsInTable;     // actual number of colors in color table
  116.      HDIB hDIBNew;
  117.     LPRGBQUAD lpColorTable;    
  118.      HPALETTE hPalNew = NULL;
  119.  
  120.     cbWritten = LoadString(hInst, wCommand, szBuffer, sizeof(szBuffer)); 
  121.     if(cbWritten == 0)
  122.         lstrcpy(szBuffer, "Unknown Command");        
  123.     UpdateStatusBar(szBuffer, 0, 0);
  124.  
  125.     // prompt user if there is an existing bitmap with changes
  126.     nResult = QuerySaveChanges(hwnd);
  127.     if (nResult == IDCANCEL)
  128.         goto ErrExit;
  129.     
  130.      // put up dialog asking for parameters
  131.     nResult = DialogBox(hInst, "FileNew", hwnd, (DLGPROC)FileNew);
  132.     if (!nResult)
  133.         goto ErrExit;  
  134.                                          
  135.     if (uNewBitsPerPixel > 8) 
  136.         // no color table if greater than 8 bpp
  137.         nNumColors = 0;
  138.     else  
  139.         // set number of colors in color table
  140.         nNumColors = 1 << uNewBitsPerPixel;                
  141.         
  142.      // Allocate memory for header & color table (if needed)
  143.     hDIBNew = GlobalAlloc(GHND, (DWORD)(sizeof(BITMAPINFOHEADER) +
  144.         nNumColors * sizeof(RGBQUAD)));
  145.  
  146.     if (!hDIBNew)
  147.     {    
  148.         DIBError(ERR_MEMORY);
  149.         goto ErrExit;
  150.     }
  151.  
  152.     lpbih = (LPBITMAPINFOHEADER)GlobalLock(hDIBNew);
  153.     if (!lpbih)
  154.      {
  155.         DIBError(ERR_LOCK);
  156.         goto ErrExitFree;  
  157.     }
  158.           
  159.     // initialize bitmap header
  160.     lpbih->biSize = sizeof(BITMAPINFOHEADER);
  161.     lpbih->biWidth = cxNewWidth;      
  162.     lpbih->biHeight = cyNewHeight;       
  163.     lpbih->biPlanes = 1;              // must be 1
  164.      lpbih->biBitCount = (WORD) uNewBitsPerPixel;
  165.     lpbih->biCompression = BI_RGB;    
  166.      lpbih->biSizeImage = WIDTHBYTES((DWORD)lpbih->biWidth *
  167.         (DWORD)lpbih->biBitCount) * lpbih->biHeight;
  168.     lpbih->biXPelsPerMeter = 0;
  169.     lpbih->biYPelsPerMeter = 0;
  170.     lpbih->biClrUsed = nNumColors;        
  171.     lpbih->biClrImportant = 0; 
  172.  
  173.     if (nNumColors)
  174.     {     
  175.         if (bPalDevice)
  176.         {
  177.             HDC hdc;
  178.  
  179.             hdc = GetDC(hwnd);
  180.             hPalNew = CreateHalftonePalette(hdc);
  181.             ReleaseDC(hwnd, hdc);
  182.         }
  183.  
  184.         // fill the color table from the logical palette
  185.         lpColorTable = (LPRGBQUAD)((LPSTR)(lpbih) + lpbih->biSize);
  186.         nColorsInTable = FillColorTable(hwnd,
  187.                                         lpColorTable,
  188.                                         hPalNew,
  189.                                         nNumColors);
  190.  
  191.         if (nColorsInTable == 0)
  192.         {
  193.             // unable to store any color values
  194.             DIBError(ERR_FILLCOLORTABLE);
  195.             goto ErrExitUnlock;  
  196.         }
  197.         else if (nColorsInTable != nNumColors)
  198.             lpbih->biClrUsed = nColorsInTable;
  199.     }
  200.      
  201.     // we've reached the point of no return (no undo)
  202.      // remove the existing DIB section
  203.     RemoveDIBSection(); 
  204.         
  205.     // set global variable to new DIB header    
  206.     hDIBInfo = hDIBNew;
  207.       
  208.     // create new DIB section
  209.     hdc = GetDC(hWndClient);  
  210.     hBitmap = CreateDIBSection(hdc, (LPBITMAPINFO)lpbih, DIB_RGB_COLORS, 
  211.         &lpvBits, 0, 0L);
  212.     ReleaseDC(hWndClient, hdc);
  213.     
  214.      if (!hBitmap || !lpvBits)
  215.     {   
  216.         DIBError(ERR_CREATEDIBSECTION); 
  217.          
  218.         if (hBitmap)            
  219.             DeleteObject(hBitmap); 
  220.             
  221.         // create default wash for palette
  222.         if (bPalDevice)
  223.         {
  224.             HDC hdc;
  225.  
  226.                 hdc = GetDC(hwnd);
  227.                 CreateHalftonePalette(hdc);
  228.             ReleaseDC(hwnd, hdc);
  229.         }
  230.                         
  231.         goto ErrExitUnlock;
  232.     } 
  233.     
  234.     // set global variable for palette
  235.     hPalette = hPalNew;
  236.    
  237.     // initialize the DIB section's bitmap surface and paint the display 
  238.      InitDIBSection(hWndClient);
  239.      
  240.     LoadString(hInst, IDS_UNTITLED, szBuffer, sizeof(szBuffer));                        
  241.     SetWindowTitle(hwnd, szBuffer);
  242.  
  243.     // adjust the size of the client window to the size of the bitmap
  244.     SizeClientWindow(hwnd);
  245.           
  246.     // unlock the DIB header, but don't free it!
  247.     GlobalUnlock(hDIBInfo);     
  248.     
  249.     // update status of menu and toolbar                                                        
  250.      // note that it's possible to save a newly initialized bitmap
  251.     EnableMenuItem(hMenu, IDM_FILESAVE, MF_ENABLED);
  252.     SendMessage(hWndToolbar, TB_ENABLEBUTTON, IDM_FILESAVE, MAKELONG(TRUE, 0));  
  253.     EnableMenuItem(hMenu, IDM_FILESAVEAS, MF_ENABLED);    
  254.     EnableMenuItem(hMenu, IDM_FILECLOSE, MF_ENABLED);
  255.     EnableMenuItem(hMenu, IDM_CLEAR, MF_ENABLED);
  256.     
  257.     // set the status bar text to original text     
  258.     UpdateStatusBar(SZDESCRIPTION, 0, 0);    
  259.     return 1;       
  260.  
  261. ErrExitUnlock:
  262.      // note: hDIBNew == hDIBInfo if failure occurred after CreateDIBSection call
  263.     GlobalUnlock(hDIBNew);    
  264.  
  265. ErrExitFree:
  266.     // note: hDIBNew == hDIBInfo if failure occurred after CreateDIBSection call    
  267.     GlobalFree(hDIBNew);
  268.               
  269. ErrExit:            
  270.     // set the status bar text to original text     
  271.     UpdateStatusBar(SZDESCRIPTION, 0, 0);
  272.     
  273.     return 0;
  274. }
  275.  
  276. //
  277. //  FUNCTION: FileNew(HWND, UINT, WPARAM, LPARAM)
  278. //
  279. //  PURPOSE:  Processes messages for "FileNew" dialog box.
  280. //
  281. //  PARAMETERS:
  282. //    hdlg - window handle of the dialog box
  283. //    wMessage - type of message
  284. //    wparam - message-specific information
  285. //    lparam - message-specific information
  286. //
  287. //  RETURN VALUE:
  288. //    TRUE - message handled
  289. //    FALSE - message not handled
  290. //
  291. //  COMMENTS:
  292. //     Display version information from the version section of the
  293. //     application resource.
  294. //
  295. //     Wait for user to click on "Ok" button, then close the dialog box.
  296. //
  297.  
  298. LRESULT CALLBACK FileNew(HWND hdlg, UINT uMessage, WPARAM wparam, LPARAM lparam)
  299. {
  300.     return DispMessage(&msdiFileNew, hdlg, uMessage, wparam, lparam);
  301. }
  302.  
  303.  
  304. //
  305. //  FUNCTION: MsgFileNewInit(HWND, UINT, WPARAM, LPARAM)
  306. //
  307. //  PURPOSE: To initialize the FileNew box with version info from resources.
  308. //
  309. //  PARAMETERS:
  310. //    hwnd - The window handing the message.
  311. //    uMessage - The message number. (unused).
  312. //    wparam - Message specific data (unused).
  313. //    lparam - Message specific data (unused).
  314. //
  315. //  RETURN VALUE:
  316. //    Always returns 0 - message handled.
  317. //
  318. //  COMMENTS:
  319. //    Uses the version apis to retrieve version information for
  320. //    each of the static text boxes in the FileNew box.
  321. //
  322.  
  323. #pragma argsused
  324. LRESULT MsgFileNewInit(HWND hdlg, UINT uMessage, WPARAM wparam, LPARAM lparam)
  325. {   
  326.     HDC hdc;
  327.     int nBitsPerPixel;      // number of color bits per pixel used by device
  328.     int nPlanes;            // number of color planes used by device
  329.     LONG lNumColors;        // number of colors displayed by device
  330.     int nBitsPerPixelID;    // dialog control for color resolution setting
  331.     
  332.     // set the icon of this dialog to the class icon
  333.     SendMessage(hdlg, WM_SETICON, (WPARAM)FALSE, (LPARAM)hIcon);
  334.         
  335.     // Center the dialog over the application window
  336.      CenterWindow(hdlg, GetWindow(hdlg, GW_OWNER));
  337.                            
  338.     // Get the color resolution used by the device driver
  339.     hdc = GetDC(hdlg);
  340.     nBitsPerPixel = GetDeviceCaps(hdc, BITSPIXEL);
  341.     nPlanes = GetDeviceCaps(hdc, PLANES);
  342.     ReleaseDC(hdlg, hdc);
  343.     
  344.     // calculate number of colors displayed by device
  345.     lNumColors = 1L << (nBitsPerPixel + nPlanes - 1);
  346.     
  347.     // Create default bitmap settings    
  348.      cxNewWidth = DEFBITMAPSIZE;
  349.     cyNewHeight = DEFBITMAPSIZE;   
  350.     SetDlgItemInt(hdlg, IDD_WIDTH, DEFBITMAPSIZE, FALSE);
  351.     SetDlgItemInt(hdlg, IDD_HEIGHT, DEFBITMAPSIZE, FALSE);    
  352.             
  353.     if (lNumColors < (1 << 4))
  354.         // device displays less than 16 colors      
  355.         nBitsPerPixelID = IDD_1;      
  356.     else if (lNumColors < (1 << 8))
  357.         // device displays less than 256 colors
  358.         nBitsPerPixelID = IDD_4;
  359.     else if (lNumColors < (1L << 16))
  360.           // display device capability is less than 64K colors
  361.         nBitsPerPixelID = IDD_8;
  362.     else if (lNumColors < (1L << 24))                  
  363.         // display device capability is less than 4M colors         
  364.         nBitsPerPixelID = IDD_16;          
  365.     else                        
  366.         // display device capability is at least 4M colors        
  367.         nBitsPerPixelID = IDD_24; 
  368.         
  369.     SendDlgItemMessage(hdlg, nBitsPerPixelID, BM_SETCHECK, 1, 0L);    
  370.  
  371.     return TRUE;
  372. }
  373.  
  374. //
  375. //  FUNCTION: MsgFileNewCommand(HWND, UINT, WPARAM, LPARAM)
  376. //
  377. //  PURPOSE: Process WM_COMMAND message sent to the FileNew box.
  378. //
  379. //  PARAMETERS:
  380. //    hwnd - The window handing the message.
  381. //    uMessage - The message number. (unused).
  382. //    wparam - Message specific data (unused).
  383. //    lparam - Message specific data (unused).
  384. //
  385. //  RETURN VALUE:
  386. //    Always returns 0 - message handled.
  387. //
  388. //  COMMENTS:
  389. //    Uses this DipsCommand function defined in wndproc.c combined
  390. //    with the cmdiFileNew structure defined in this file to handle
  391. //    the command messages for the FileNew dialog box.
  392. //
  393.  
  394. #pragma argsused
  395. LRESULT MsgFileNewCommand(HWND   hwnd,
  396.                                 UINT   uMessage,
  397.                                 WPARAM wparam,
  398.                                 LPARAM lparam)
  399. {
  400.      return DispCommand(&cmdiFileNew, hwnd, wparam, lparam);
  401. }
  402.  
  403. //
  404. //  FUNCTION: CmdFileNewValidate(HWND, WORD, HWND)
  405. //
  406. //  PURPOSE: Validate characters for bitmap size entered in File New dialog
  407. //
  408. //  PARAMETERS:
  409. //    hwnd - The window handling the command.
  410. //    wCommand - The command to be handled (unused).
  411. //    hwndCtrl - NULL (unused).
  412. //
  413. //  RETURN VALUE:
  414. //    Always returns TRUE.
  415. //
  416. //  COMMENTS:
  417. //
  418. //
  419.  
  420. #pragma argsused
  421. LRESULT CmdFileNewEditNotify(HWND hdlg, WORD wCommand, WORD wNotify, HWND hwndCtrl)
  422. {   
  423.     int nNumChars, nValue;
  424.     char szBuffer[5];
  425.     BOOL fTranslated;    
  426.  
  427.     if (wNotify != EN_UPDATE || fInEditNotify)
  428.           // ignore all other notifications except EN_UPDATE, and don't recurse!
  429.         return TRUE;        
  430.                       
  431.     // validate characters input into edit control
  432.     nNumChars = GetDlgItemText(hdlg, wCommand, szBuffer, 5);  
  433.     nValue = GetDlgItemInt(hdlg, wCommand, &fTranslated, FALSE);
  434.                                    
  435.     switch (wCommand)
  436.     {
  437.         case IDD_WIDTH:
  438.             if (nNumChars == 0)     
  439.                 // the Width edit control is empty
  440.                      cxNewWidth = NOBITMAPSIZE;
  441.             else if (fTranslated && nValue <= MAXBITMAPSIZE)       
  442.                 // the user input a value in accepted range
  443.                 cxNewWidth = nValue;     
  444.             else 
  445.             {                            
  446.                 // bad user input, so reset to previous value  
  447.                 
  448.                 // first set the flag to prevent recursion
  449.                 fInEditNotify = TRUE;
  450.                 
  451.                 if (cxNewWidth == NOBITMAPSIZE)
  452.                           // previously the Width edit control was empty
  453.                     SetDlgItemText(hdlg, wCommand, "");
  454.                 else
  455.                     // previously the Width edit control had a value
  456.                     SetDlgItemInt(hdlg, wCommand, cxNewWidth, FALSE);
  457.                                      
  458.                 // clear the recursion flag
  459.                 fInEditNotify = FALSE;                    
  460.                                                      
  461.                 // notify the user
  462.                 MessageBeep((UINT)-1);      
  463.             }    
  464.  
  465.             break;       
  466.             
  467.         case IDD_HEIGHT:
  468.             if (nNumChars == 0)          
  469.                 // the Height edit control is empty
  470.                 cyNewHeight = NOBITMAPSIZE;             
  471.             else if (fTranslated && nValue <= MAXBITMAPSIZE)
  472.                 // accept the user input
  473.                 cyNewHeight = nValue;
  474.             else
  475.             {
  476.                      // bad user input, so reset to previous value
  477.        
  478.                 // first set the flag to prevent recursion
  479.                 fInEditNotify = TRUE;
  480.                                             
  481.                 if (cyNewHeight == NOBITMAPSIZE)
  482.                     // previously the Height edit control was empty
  483.                     SetDlgItemText(hdlg, wCommand, "");
  484.                 else                               
  485.                     // previously the Height edit control had a value
  486.                     SetDlgItemInt(hdlg, wCommand, cyNewHeight, FALSE); 
  487.                     
  488.                      // clear the recursion flag
  489.                 fInEditNotify = FALSE;                    
  490.                 
  491.                 // notify the user
  492.                 MessageBeep((UINT)-1);           
  493.             }        
  494.             
  495.             break;
  496.             
  497.         default:
  498.             break;
  499.     }
  500.  
  501.     return TRUE;
  502. }
  503.        
  504. //
  505. //  FUNCTION: CmdFileNewDone(HWND, WORD, HWND)
  506. //
  507. //  PURPOSE: Free the FileNew box and related data.
  508. //
  509. //  PARAMETERS:
  510. //    hwnd - The window handling the command.
  511. //    wCommand - The command to be handled (unused).
  512. //    hwndCtrl - NULL (unused).
  513. //
  514. //  RETURN VALUE:
  515. //    Always returns TRUE.
  516. //
  517. //  COMMENTS:
  518. //    Calls EndDialog to finish the dialog session.
  519. //
  520.  
  521. #pragma argsused
  522. LRESULT CmdFileNewDone(HWND hdlg, WORD wCommand, WORD wNotify, HWND hwndCtrl)
  523. {
  524.      switch (wCommand)
  525.     {
  526.         case IDOK:
  527.         {       
  528.             char szBuffer[40];
  529.             
  530.             // the edit controls are already validated, but could be empty  
  531.             
  532.             if (cxNewWidth == NOBITMAPSIZE)
  533.             {   
  534.                 LoadString(hInst, ERR_WIDTH, szBuffer, sizeof(szBuffer)); 
  535.                 MessageBox(hdlg, szBuffer, szAppName, MB_ICONHAND);
  536.                      SetFocus(GetDlgItem(hdlg, IDD_WIDTH));
  537.                 return TRUE;
  538.             }
  539.             
  540.             if (cyNewHeight == NOBITMAPSIZE)
  541.             {   
  542.                 LoadString(hInst, ERR_HEIGHT, szBuffer, sizeof(szBuffer));  
  543.                 MessageBox(hdlg, szBuffer, szAppName, MB_ICONHAND);
  544.                 SetFocus(GetDlgItem(hdlg, IDD_HEIGHT));
  545.                 return TRUE;
  546.             }                    
  547.             
  548.                 // we have the bitmap size, now get the color resolution
  549.             if (SendDlgItemMessage(hdlg, IDD_1, BM_GETCHECK, 0, 0L))
  550.                 uNewBitsPerPixel = 1;
  551.             else if (SendDlgItemMessage(hdlg, IDD_4, BM_GETCHECK, 0, 0L))
  552.                 uNewBitsPerPixel = 4;            
  553.             else if (SendDlgItemMessage(hdlg, IDD_8, BM_GETCHECK, 0, 0L))
  554.                 uNewBitsPerPixel = 8;                                     
  555.             else if (SendDlgItemMessage(hdlg, IDD_16, BM_GETCHECK, 0, 0L))
  556.                 uNewBitsPerPixel = 16;                        
  557.             else
  558.                 uNewBitsPerPixel = 24;
  559.        
  560.                  // exit the dialog
  561.             EndDialog(hdlg, TRUE);         
  562.             break;
  563.         }
  564.                 
  565.         case IDCANCEL:
  566.             // cancel the dialog
  567.             EndDialog(hdlg, FALSE);
  568.             break;
  569.             
  570.         default:
  571.             break;
  572.      }
  573.     
  574.     return TRUE;
  575. }
  576.        
  577.